package net.sxnic.workflow.task;

import net.sxinfo.core.dao.Page;
import net.sxinfo.core.spring25.Manager;
import net.sxnic.workflow.node.Node;

import org.springframework.transaction.annotation.Transactional;

/**
 * 
 * Comments: Task 业务层接口
 * <p>
 * Author：孙宇飞
 * <p>
 * Create Date：2009-10-14
 * <p>
 * 
 * 
 */
@Transactional(readOnly = true)
public interface TaskManager extends Manager<Task, String> {

	/**
	 * 重新激活任务
	 * 
	 * @param task
	 *            要激活的任务
	 * @param operator
	 *            操作者。普通用户不能操作，一般为管理员
	 */
	@Transactional(readOnly = false)
	void reactiveTask(Task task, String operator);

	/**
	 * 挂起任务
	 * 
	 * @param task
	 *            要挂起的任务
	 * @param operator
	 *            操作者。普通用户不能操作，一般为管理员
	 */
	@Transactional(readOnly = false)
	void suspendTask(Task task, String operator);

	/**
	 * 逻辑删除任务
	 * 
	 * @param task
	 *            要删除的任务
	 * @param operator
	 *            操作者。普通用户不能操作，一般为管理员
	 */
	@Transactional(readOnly = false)
	void deleteTask(Task task, String operator);

	/**
	 * 撤销任务
	 * 
	 * @param task
	 *            要撤销的任务
	 * @param operator
	 *            操作者。普通用户可能操作
	 */
	@Transactional(readOnly = false)
	boolean cancelTask(String taskId, String operator) throws Exception;

	/**
	 * 结束任务
	 * 
	 * @param task
	 *            要结束的任务
	 * @throws TaskException
	 * @throws TaskStatusException
	 *             如果状态不对可能抛此任务
	 */
	@Transactional(readOnly = false)
	void endTask(String taskId) throws TaskException, TaskStatusException;

	/**
	 * 结束任务
	 * 
	 * @param task
	 *            要结束的任务
	 * @param nextAssignee
	 *            选中的接收人
	 * @param comment
	 *            意见
	 * @throws TaskException
	 * @throws TaskStatusException
	 */
	@Transactional(readOnly = false)
	void endTask(Task task, String nextAssignees, String comment) throws TaskException, TaskStatusException;

	/**
	 * 保存 意见
	 * 
	 * @param taskId
	 * @param taskComment
	 */
	@Transactional(readOnly = false)
	void updateComment(String taskId, String taskComment);

	/**
	 * 根据 用户名 和 类型 查询任务列表page
	 * 
	 * @param page
	 * @param pageSize
	 * @param userName
	 *            任务执行者
	 * @param type
	 *            类型：收文，发文，通知通告
	 * @return
	 */
	Page getPageByUserName(int page, int pageSize, String userName, String type);


	/**
	 * 任务退回
	 * 
	 * @param taskId
	 *            当前任务id
	 * @param contiuneType
	 *            退回之后，继续的方式。是直接跳到返回处还是重新走流程
	 * @param reason
	 *            退回原因
	 */
	@Transactional(readOnly = false)
	void returnBack(String taskId, String continueType, String reason);

	/**
	 * 任务退回
	 * 
	 * @param taskId
	 *            当前任务Id
	 * @param toNodeName
	 *            要退回到得节点名
	 * @param toAssignee
	 *            可以遇见的接收人
	 * @param continueType
	 *            返回方式
	 * @param comment
	 *            退回意见
	 */
	@Transactional(readOnly = false)
	void returnBack(String taskId, String toNodeName, String toAssignee, String continueType, String comment);

	/**
	 * 查询第一个任务
	 * 
	 * @param entityId
	 * @return
	 */
	Task findFirstTask(String entityId);

	/**
	 * 逻辑上删除上task
	 * 
	 * @param taskId
	 */
	@Transactional(readOnly = false)
	void deleteTask(String taskId);

	/**
	 * 查询退回人的任务，主要是为了找到退回意见
	 * 
	 * @param processId
	 *            流程Id
	 * @param assignee
	 *            退回人
	 * @return
	 */
	Task findReturnBackTask(String processId, String assignee);
	
	/**
	 * 创建任务 （20131201以后主要以此方法来创建任务，而且专用于项目申报类）
	 * 
	 * @param nextNode
	 *            下一个节点名称
	 * @param assignee
	 *            任务的接受者，或者说承办人
	 * @param fromTask
	 *            来源Task
	 * @return task
	 */
	@Transactional(readOnly = false)
	Task createTask(Node nextNode, String assignee, Task fromTask);

	/**
	 * 在启动起始节点处，自己给自己创建任务
	 * 
	 * @param entityId
	 *            实体Id
	 * @param CatalogAlias
	 *            大类别名
	 * @param assignee
	 *            当前用户名
	 * @return
	 */
	@Transactional(readOnly = false)
	Task createSelfTaskatStartNode(String entityId, String CatalogAlias, String assignee);	
}
